package com.zeng.ssm.service.support.trans.scanner;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;

import java.util.Set;

/**
 * 客户端+服务端-Handler扫描Configurer
 *
 * @author zengwanlin
 * @date 2022-12-28T16:14
 */
public class TransScannerConfigurer implements BeanDefinitionRegistryPostProcessor, SmartApplicationListener {

    private Logger logger = LoggerFactory.getLogger(TransScannerConfigurer.class);

    /**
     * 扫描包路径
     */
    private Set<String> basePackages;

    /**
     * Handler别名Set
     */
    private Set<String> aliasSet = null;

    public Set<String> getBasePackages() {
        return basePackages;
    }

    public void setBasePackages(Set<String> basePackages) {
        this.basePackages = basePackages;
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        if (CollectionUtils.isEmpty(this.basePackages)) {
            throw new NullPointerException("basePackages为空");
        }
        logger.info(com.zeng.ssm.service.support.trans.scanner.TransHandlerScanner.class.getSimpleName() + "扫描路径：{}", this.basePackages);
        com.zeng.ssm.service.support.trans.scanner.TransHandlerScanner scanner = new com.zeng.ssm.service.support.trans.scanner.TransHandlerScanner(beanDefinitionRegistry);
        scanner.setIncludeAnnotationConfig(false);
        scanner.setScopeMetadataResolver(new com.zeng.ssm.service.support.trans.scanner.TransHandlerScanner.PrototypeMetadataResolver());
        this.aliasSet = scanner.scanHandler(this.basePackages.toArray(new String[this.basePackages.size()]));
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        // left intentionally blank
    }

    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        return ClassUtils.isAssignable(ContextRefreshedEvent.class, eventType);
    }

    @Override
    public boolean supportsSourceType(Class<?> sourceType) {
        return sourceType != null && ClassUtils.isAssignable(ApplicationContext.class, sourceType);
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        ContextRefreshedEvent contextRefreshedEvent = (ContextRefreshedEvent) event;
        ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext();
        if (CollectionUtils.isEmpty(this.aliasSet)) {
            return;
        }
        logger.info("实例化Handler开始");
        for (String alias : this.aliasSet) {
            applicationContext.getBean(alias);
        }
        this.aliasSet = null;
        logger.info("实例化Handler结束");
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }

}
